package cn.tedu.zx.sso.security.service.amdin.impl;

import cn.tedu.zx.common.domain.ZxAuthenticationInfo;
import cn.tedu.zx.common.exception.ServiceException;
import cn.tedu.zx.common.restful.ResponseCode;
import cn.tedu.zx.common.utils.JwtTokenUtils;
import cn.tedu.zx.sso.mapper.admin.AdminLoginLogMapper;
import cn.tedu.zx.sso.pojo.dto.AdminLoginDTO;
import cn.tedu.zx.sso.pojo.entity.AdminUserDetails;
import cn.tedu.zx.sso.security.service.amdin.AdminSSOUserDetailsService;
import cn.tedu.zx.sso.security.service.amdin.IAdminSSOService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class AminSSOServiceImpl implements IAdminSSOService {
    @Autowired
    private AdminSSOUserDetailsService userDetailsService;
    @Autowired
    private AdminLoginLogMapper adminLoginLogMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtils jwtTokenUtils;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public String doLogin(AdminLoginDTO adminLoginDTO) {
        //生产token

        AdminUserDetails userDetails =
                (AdminUserDetails) userDetailsService.loadUserByUsername(adminLoginDTO.getUsername());
        if (userDetails==null){
            throw new ServiceException(ResponseCode.BAD_REQUEST,"登录失败！用户名密码错误");
        }
        if (!passwordEncoder.matches(adminLoginDTO.getPassword(),userDetails.getPassword())){
            throw new ServiceException(ResponseCode.BAD_REQUEST,"登录失败！用户名密码错误");
        }
        ZxAuthenticationInfo authenticationInfo=generateFromAdmin(userDetails);
        String token=jwtTokenUtils.generateToken(authenticationInfo);
        //TODO  记录登录日志
        //TODO  AdminLoginLog还没创建
        return token;
    }

    private ZxAuthenticationInfo generateFromAdmin(AdminUserDetails userDetails) {
        List<GrantedAuthority> authorities = (List<GrantedAuthority>) userDetails.getAuthorities();
        List<String> authorityValues=new ArrayList<>();
        for (GrantedAuthority authority : authorities) {
            String value=authority.getAuthority();
            authorityValues.add(value);
        }
        ZxAuthenticationInfo userInfo=new ZxAuthenticationInfo();
        userInfo.setId(userDetails.getId());
        userInfo.setUsername(userDetails.getUsername());
        userInfo.setUserType("ADMIN");
        userInfo.setAuthorities(authorityValues);
        log.info("{}",userInfo);

        return userInfo;
    }

    @Value("${jwt.tokenHead}")
    private String tokenHead;//Bearer
    @Override
    public void doLogout(String token) {
        if (token!=null&&token.startsWith(tokenHead)){
            //拿到jwt token
            String authToken = token.substring(tokenHead.length());
            String lockedTokenList="token_list_.lock";
            Long add = stringRedisTemplate.boundSetOps(lockedTokenList).add(authToken);
            if(add==0){
                throw new ServiceException(ResponseCode.CONFLICT,"当前用户已经登出,不必重复登出");
            }
        }else{
            //header不存在token
            throw new ServiceException(ResponseCode.NOT_FOUND,"当前客户端没有登录状态");
        }
    }
}
